# /bin/env python
# -*- coding: utf-8 -*-

import time
import struct
import select
from threading import Timer
import socket
import random

SENDER_IP = '0.0.0.0'
SENDER_PORT = 1501
MC_PORT = 1234
MC_GROUP = '224.1.1.1'
MC_TTL = 255
EXIT = False

def sender():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    #s.bind((SENDER_IP, SENDER_PORT))
    # Set time-to-live (optional)
    ttl_bin = struct.pack('@i', MC_TTL)
    s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin)
    status = s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
            socket.inet_aton(MC_GROUP)+socket.inet_aton(SENDER_IP))
    for i in range(10):
        data = 'cisco'
        s.sendto(data + '\0', (MC_GROUP, MC_PORT))
        print 'send data ok!'
        random.seed(time.time())
        t = random.randint(0, 5)
        print 'sleep %d sec.' % t
        time.sleep(t)

'''
def receiver():
    s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    s.bind((SENDER_IP, MC_PORT))
    #tell the kernel that we are a multicast socket
    #s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
    status = s.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP,
        inet_aton(MC_GROUP) + inet_aton(SENDER_IP));
    s.setblocking(0)

    inputs = [s]
    outputs = []
    timeout = 3

    while True:
        readable, writable, exceptional = select.select(inputs, outputs, inputs, timeout)
        if not (readable or writable or exceptional) :
            print "Time out %d!" % timeout
            continue
        for rd in readable:
            if rd is s:
                try:
                    data, addr = s.recvfrom(1024)
                except Exception as e:
                    print 'error:', str(e)
                else:
                    print "Receive data!"
                    print "TIME:" , time.time(), timeout
                    print "FROM: ", addr
                    print "DATA: ", data
'''
def receiver(timeout):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('0.0.0.0', MC_PORT))
    status = s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
            socket.inet_aton(MC_GROUP)+socket.inet_aton(SENDER_IP))
    s.setblocking(0)

    inputs = [s]
    outputs = []
    ctm_list = {}

    start_tm = int(time.time())
    print 'start_tm:', start_tm

    while True:
        end_tm = int(time.time())
        if end_tm - start_tm >= timeout:
            print 'end_tm:', end_tm
            break
        readable, writable, exceptional = select.select(inputs, outputs, inputs, 1)
        if not (readable or writable or exceptional) :
            #print "Time out ! "
            continue
        for rd in readable:
            if rd is s:
                data, addr = s.recvfrom(1024)
                print "Receive data!", time.time(), addr, data
                ctm_list[addr] = data
    return ctm_list

if __name__ == "__main__":
    tjob = Timer(1, sender)
    tjob.start()
    ret = receiver(10)
    print ret
